package panda.client.listeners;

import panda.client.Cardpanda;
import panda.client.ui.observable.ObservableLastMousedCard;
import panda.client.ui.widgets.DraggableCard;
import panda.client.ui.widgets.NoteTip;
import panda.client.ui.widgets.ZoomManager;

import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;

/**
 * Central controller for key inputs in CardPanda. Make sure key inputs that fizzle (targets no initialized) fizzle
 * gracefully. Note that some updateServer calls are made directly here, while others are embedded in the methods in
 * ClientModel.java. This is a poor design choice that I have yet to fix =(
 * 
 * @author zane.tian@gmail.com
 */
public class PandaKeyDownHandler implements KeyDownHandler {
	public static boolean holdingShift = false;
	public static boolean holdingCtrl = false;

	private void sendModelUpdateToServer() {
		Cardpanda.sendModelUpdateToServer(Cardpanda.clientModel.getSessionID());
	}

	public void onKeyDown(KeyDownEvent event) {
		int keyCode = event.getNativeKeyCode();
	// NoteTip.get().logPersonalNote("keyDown: " + keyCode + " modifiers: " + modifiers);
		ObservableLastMousedCard lastMousedOver = Cardpanda.clientModel.getObsLastMousedCard();

		if(keyCode == KeyCodes.KEY_SHIFT) {
			holdingShift = true;
		}
		
		if(keyCode == KeyCodes.KEY_CTRL) {
			holdingCtrl = true;
		}

		if(Cardpanda.tokenMenu.isOpen()) {
			NoteTip.get().logPersonalNote("You need to close the token creator popup window to access CardPanda hotkeys.",
					true);

		} else {
			ZoomManager zoom = Cardpanda.zoomManager;

			/* debug: card title size changes in binEx. doesn't take effect immediately though. wait til next update */
			if(keyCode == '1') {
			}
			
			if(keyCode == '2') {
			}
			
			if(keyCode == '3') {
				// BinExplorer.size = BinExplorer.CardTitleDimension.half;
				// BinExplorer.size = BinExplorer.CardTitleDimension.threeQuarter;
				// BinExplorer.size = BinExplorer.CardTitleDimension.full;
			}
			
			/* zoom: shows a blown up version of the card unless it is face down and you don't own it */
			if(keyCode == 'Z') {
				if(!zoom.isZooming() && lastMousedOver.hasCard()) {
					DraggableCard card = lastMousedOver.getCard();
					
					if(card.isFaceDown() && !card.isMine()) {
						zoom.show(lastMousedOver.getCard(), false);
					} else {
						zoom.show(lastMousedOver.getCard(), true);
					}
				}
			}

			/* Tap the last moused over draggable card if lastmousedovercard isn't null and if the card is in play */
			if(keyCode == 'T' && lastMousedOver.hasCard() && Cardpanda.clientModel.inPlay(lastMousedOver.getCard())) {
				DraggableCard tapTarget = lastMousedOver.getCard();
				Cardpanda.clientModel.tapToggle(tapTarget);

				sendModelUpdateToServer();
			}
			
			/* untap all permanents you own */
			if(keyCode == 'U') {
				Cardpanda.clientModel.untapOwnedPermanents();
				
				String logForMe = "You untap.";
				String logForOthers = Cardpanda.clientModel.getSessionID().getName() + " untaps.";
				NoteTip.get().log(logForMe, logForOthers);
				
				sendModelUpdateToServer();
			}
			
			/* flip card if lastMousedOverCard exists and is in play */
			if(keyCode == 'F' && lastMousedOver.hasCard() && Cardpanda.clientModel.inPlay(lastMousedOver.getCard())) {
				DraggableCard flipTarget = lastMousedOver.getCard();
				
				if(flipTarget.isFaceDown()) {
					flipTarget.flipUp();

					/* this needs to come after the flipUp call because that affects the card's name */
					/* flipUp turns "a face down card" to the actual card name */
					String logForMe = "You turn " + flipTarget.getName() + " face up.";
					String logForOthers = Cardpanda.clientModel.getSessionID().getName() + " turns " + flipTarget.getName()
							+ " face up.";
					NoteTip.get().log(logForMe, logForOthers);
				} else {
					String logForMe = "You turn " + flipTarget.getName() + " face down.";
					String logForOthers = Cardpanda.clientModel.getSessionID().getName() + " turns " + flipTarget.getName()
							+ " face up.";
					NoteTip.get().log(logForMe, logForOthers);
					
					flipTarget.flipOver();
				}
				
				
				sendModelUpdateToServer();
			}

			/* shuffle */
			if(keyCode == 'S') {
				Cardpanda.clientModel.shuffleLibrary();
				sendModelUpdateToServer();
			}

			/* reveal a card at raNdom from your hand */
			if(keyCode == 'N') {
				Cardpanda.clientModel.revealRandomCardInHand(true);
			}

			/* reveal a card from the top of your library */
			if(keyCode == 'Q') {
				boolean shift = event.isShiftKeyDown();
				Cardpanda.clientModel.revealTopCardOfLibrary(true, shift);
			}

			/* put a card at the bottom of your library */
			if(keyCode == 'B') {
				Cardpanda.clientModel.putCardAtLibraryBottom(true);
			}

			/* draw a card */
			if(keyCode == 'D') {
				Cardpanda.clientModel.drawCardFromLibrary(true);
			}

			/* Set z-index TODO: shouldn't trigger when the main canvas doesn't have focus. */
			if(keyCode == KeyCodes.KEY_UP) {
				if(lastMousedOver.hasCard()) {
					DraggableCard card = lastMousedOver.getCard();
					card.setZIndex(card.getZIndex() + 1);

					String logForMe = "You set " + card.getName() + "'s z-index to " + card.getZIndex();
					String logForOthers = Cardpanda.clientModel.getSessionID().getName() + " sets " + card.getName()
							+ "'s z-index to " + card.getZIndex();
					NoteTip.get().log(logForMe, logForOthers);
					sendModelUpdateToServer();
				}
			}

			if(keyCode == KeyCodes.KEY_DOWN) {
				if(lastMousedOver.hasCard()) {
					DraggableCard card = lastMousedOver.getCard();
					card.setZIndex(card.getZIndex() - 1);
					String logForMe = "You set " + card.getName() + "'s z-index to " + card.getZIndex();
					String logForOthers = Cardpanda.clientModel.getSessionID().getName() + " sets " + card.getName()
							+ "'s z-index to " + card.getZIndex();
					NoteTip.get().log(logForMe, logForOthers);
					sendModelUpdateToServer();
				}
			}

			/* Bin Explorer Visibility Toggles TODO: add opponent visibility stuff here with h = hand vis */
			if(keyCode == 'L') {
				Cardpanda.clientModel.toggleLibraryVisibility();
			}

			if(keyCode == 'G') {
				Cardpanda.clientModel.toggleGraveyardVisibility();
			}
		}
	}
}